//
//  WCFile.m
//  WabbitCode
//
//  Created by William Towe on 1/22/09.
//  Copyright 2009 Revolution Software. All rights reserved.
//

#import "WCFile.h"
#import "WCMacros.h"
#import "NSImage+WCExtensions.h"
#import "WCProject.h"
#import "WCMacros.h"
#import "NSWorkspace+WCExtensions.h"
#import "WCFileReference.h"


#define kWCFFileReferenceKey @"fileReference"
#define kWCFGetInfoWindowFrameKey @"getInfoWindowFrame"

static NSFileManager *fm = nil;
static NSWorkspace *sw = nil;

@implementation WCFile
#pragma mark *** Subclass Overrides ***
+ (void)initialize {
	fm = [NSFileManager defaultManager];
	sw = [NSWorkspace sharedWorkspace];
}

- (void)dealloc {
	[_fileReference release];
	[_absoluteFilePath release];
	[super dealloc];
}

- (BOOL)isLeaf {
	return YES;
}

- (NSImage *)icon { 
	NSImage *i = [[self fileReference] icon];
	[i setSize:NSMakeSize(16.0, 16.0)];
	return i;
}

- (NSString *)name {
	return [[self absoluteFilePath] lastPathComponent];
}

- (void)setName:(NSString *)value {
	[(WCFileReference *)[self fileReference] setName:value];
	[self setRecacheAbsoluteFilePath:YES];
}

- (NSString *)nodeToolTip {
	return [self absoluteFilePath];
}

- (BOOL)canGroupNode {
	return YES;
}

- (BOOL)canUngroupNode {
	return NO;
}

- (BOOL)isValid {
	return [fm fileExistsAtPath:[self absoluteFilePath]];
}

- (BOOL)canRenameNode {
	return ([self isValid]);
}

- (NSString *)fileUTI {
	return [sw typeOfFile:[self absoluteFilePath] error:NULL];
}

- (NSString *)fileExtension {
	return [[self absoluteFilePath] pathExtension];
}

- (NSImage *)fileIcon {
	return [[self fileReference] icon];
}

- (BOOL)isDragable {
	return YES;
}

#pragma mark NSCoding Protocol
- (id)initWithCoder:(NSCoder *)coder {
	if (!(self = [super initWithCoder:coder]))
		return nil;
	
	_fileReference = [[coder decodeObjectForKey:kWCFFileReferenceKey] retain];
	_getInfoWindowFrame = NSRectFromString([coder decodeObjectForKey:kWCFGetInfoWindowFrameKey]);
	
	return self;
}

- (void)encodeWithCoder:(NSCoder *)coder {
	[super encodeWithCoder:coder];
	[coder encodeObject:_fileReference forKey:kWCFFileReferenceKey];
	[coder encodeObject:NSStringFromRect(_getInfoWindowFrame) forKey:kWCFGetInfoWindowFrameKey];
}
#pragma mark NSCopying Protocol
- (id)copyWithZone:(NSZone *)zone {
	WCFile *copy = [super copyWithZone:zone];
	
	copy->_fileReference = [_fileReference retain];
	copy->_project = _project;
	
	return copy;
}
#pragma mark *** Public Methods ***

#pragma mark Accessors
@synthesize fileReference=_fileReference,project=_project,getInfoWindowFrame=_getInfoWindowFrame;

@dynamic recacheAbsoluteFilePath;
- (BOOL)recacheAbsoluteFilePath {
	return _WCFileFlags.recacheAbsoluteFilePath;
}
- (void)setRecacheAbsoluteFilePath:(BOOL)flag {
	_WCFileFlags.recacheAbsoluteFilePath = flag;
}

@dynamic absoluteFilePath;
- (NSString *)absoluteFilePath {
	if (!_absoluteFilePath || _WCFileFlags.recacheAbsoluteFilePath) {
		_WCFileFlags.recacheAbsoluteFilePath = NO;
		
		[_absoluteFilePath release];
		_absoluteFilePath = [[[self fileReference] path] retain];
	}
	return _absoluteFilePath;
}
- (void)setAbsoluteFilePath:(NSString *)value {	
	[self willChangeValueForKey:@"icon"];
	[self willChangeValueForKey:@"name"];
	//_WCFileFlags.recacheAbsoluteFilePath = YES;
	[_absoluteFilePath release];
	_absoluteFilePath = [value retain];
	[[self fileReference] setPath:value];
	[self didChangeValueForKey:@"icon"];
	[self didChangeValueForKey:@"name"];
}

@dynamic absoluteFilePathByAbbreviatingTildeInPath;
- (NSString *)absoluteFilePathByAbbreviatingTildeInPath {
	return [[self absoluteFilePath] stringByAbbreviatingWithTildeInPath];
}

@dynamic folderPath; 
- (NSString *)folderPath {
	return [[self absoluteFilePath] stringByDeletingLastPathComponent];
}

@dynamic numberOfFileErrors;
- (NSNumber *)numberOfFileErrors {
	return nil;
}

@dynamic numberOfFileWarnings;
- (NSNumber *)numberOfFileWarnings {
	return nil;
}
#pragma mark Creation
+ (id)fileWithFilePath:(NSString *)filePath inProject:(WCProject *)project; {
	return [self fileWithFilePath:filePath name:nil inProject:project];
}
+ (id)fileWithFilePath:(NSString *)filePath name:(NSString *)name inProject:(WCProject *)project; {
	return [[[[self class] alloc] initWithFilePath:filePath name:name inProject:project] autorelease];
}

- (id)initWithFilePath:(NSString *)filePath inProject:(WCProject *)project; {
	return [self initWithFilePath:filePath name:nil inProject:project];
}
- (id)initWithFilePath:(NSString *)filePath name:(NSString *)name inProject:(WCProject *)project; {
	if (!(self = [super initWithNodeName:name]))
		return nil;
	
	_fileReference = [[WCFileReference alloc] initWithFilePath:filePath];
	_project = project;
	
	return self;
}

#pragma mark *** Private Methods ***

@end
